home *** CD-ROM | disk | FTP | other *** search
- /*=======================================================*/
- /* TVJNEW.C */
- /* */
- /* (c) Copyright 1988 Ralf Brown All Rights Reserved */
- /* May be freely copied for noncommercial use, so long */
- /* as this copyright notice remains intact, and any */
- /* changes are marked in the comment blocks preceding */
- /* functions. */
- /*=======================================================*/
-
- #pragma inline
-
- #include <string.h>
- #include <stdarg.h>
- #include "tvapi.h"
-
- #define STACKSIZE 256
-
- static int _TV_newapp_mutex_ = 0 ;
-
- /*======================================================*/
-
- struct EXEC_block {
- int env ; /* segment of environment */
- char far *cmdline ;
- char far *fcb_1 ;
- char far *fcb_2 ;
- } ;
-
- static char far *new_program ;
- static struct EXEC_block far *exec_block ;
-
- /*======================================================*/
- /* launch_app fork to here, and then EXEC the program */
- /* Ralf Brown 5/10/88 */
- /* Ralf Brown 6/6/88 added own spawn routine */
- /*======================================================*/
-
- static void launch_app(int parent)
- {
- struct EXEC_block far *exec_blk = exec_block ;
- char far *program = new_program ;
-
- (void) parent ; /* satisfy TurboC's warnings about unused parameters */
- /* we've now got copies of the static variables, so we can unblock */
- _TV_newapp_mutex_ = 0 ;
-
- /* EXEC the program and get its exit code */
- asm push ds
- asm mov bx,exec_block
- asm mov es,exec_block+2
- asm mov dx,new_program
- asm mov ds,new_program+2
- asm mov ax,4b00h
- asm int 21h
- asm pop ds
- asm jnc no_error
- /* waiting for exit code with INT 21h/AH=4Dh hangs process */
- no_error:
-
- free((char *) program) ;
- free((char *) exec_blk->fcb_1) ;
- free((char *) exec_blk->cmdline) ;
- free((char *) exec_blk) ;
- }
-
- /*======================================================*/
- /* TVapp_new create new application in current process */
- /* Ralf Brown 5/10/88 */
- /* Ralf Brown 8/6/88 made it use vararg list, and */
- /* renamed to TVspawnve. TVapp_new now */
- /* calls this function */
- /*======================================================*/
-
- OBJECT pascal TVspawnve(OBJECT win,int row,int col,int rows,int cols,
- int switch_menu,char *program,va_list args,int env)
- {
- OBJECT new_app = NIL ;
- char *arg ;
- int cmd_len = 0 ;
- char *cmd_line, *cmd, *rest ;
- struct fcb *fcb1, *fcb2 ;
-
- /* allocate space for the commandline and FCBs */
- if ((cmd_line = malloc(128)) == NULL)
- goto error2 ;
- if ((fcb1 = malloc(2*sizeof(struct fcb))) == NULL)
- {
- free(cmd_line) ;
- goto error2 ;
- }
- cmd = cmd_line+1 ;
- fcb2 = fcb1+1 ;
- /* we'll be overwriting static vars, so can only have one copy here at a time */
-
- busy_wait:
- asm mov ax,1
- asm lock xchg ax,_TV_newapp_mutex_
- asm or ax,ax
- asm jz wait_done
- TVpause() ;
- asm jmp busy_wait
- wait_done:
-
- if ((new_program = (char far *)malloc(strlen(program)+1)) != NULL)
- strcpy((char *)new_program, program) ;
- else
- {
- free(cmd_line) ;
- free(fcb1) ;
- goto error ;
- }
- if ((exec_block = (struct EXEC_block far *)malloc(sizeof(struct EXEC_block))) != NULL)
- {
- exec_block->env = env ;
- exec_block->cmdline = (char far *)cmd_line ;
- exec_block->fcb_1 = (char far *)fcb1 ;
- exec_block->fcb_2 = (char far *)fcb2 ;
- }
- else
- {
- free(cmd_line) ;
- free(fcb1) ;
- free((char *)new_program) ;
- goto error ;
- }
- /* then concatenate the args to form the commandline */
- (void) va_arg( args, char * ) ; /* skip argv[0] */
- while ((arg = va_arg(args, char *)) != NULL)
- {
- while (*arg && cmd_len < 126)
- {
- *cmd++ = *arg++ ;
- cmd_len++ ;
- }
- if (cmd_len >= 126)
- {
- cmd_len = 126 ;
- break ;
- }
- else
- {
- *cmd++ = ' ' ; /* separate args by blanks */
- cmd_len++ ;
- }
- }
- cmd_line[0] = cmd_len ;
- cmd_line[cmd_len+1] = '\r' ;
- va_end( args ) ;
- /* now set up the FCBs */
- rest = parsfnm( cmd_line+1, (struct fcb *)fcb1, 1 ) ; /* 1=ignore leading separators */
- if (rest) /* was first parse successful? */
- rest = parsfnm( rest, (struct fcb *)fcb2, 1 ) ;
- /* and launch the program */
- new_app = TVtask_new(win,NULL,row,col,rows,cols,NULL,STACKSIZE,launch_app,switch_menu) ;
- if (new_app)
- return new_app ;
- error:
- _TV_newapp_mutex_ = 0 ; /* release exclusion since we never launched the program */
- error2:
- return new_app ;
- }
-
- /*======================================================*/
- /* TVapp_new create new application in current process */
- /* Ralf Brown 5/10/88 */
- /*======================================================*/
-
- OBJECT cdecl TVapp_new(OBJECT win,int row,int col,int rows,int cols,
- int switch_menu,char *program, ...)
- {
- return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,0) ;
- }
-
- OBJECT cdecl TVspawnle(OBJECT win,int row,int col,int rows,int cols,
- int switch_menu,char **env,char *program, ...)
- {
- int env_seg ;
-
- env_seg = 0 ; /* until I figure out how to set it */
- return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,env_seg) ;
- }
-
- /* End of TVJNEW.C */
-